﻿#include "ssDBThread.h"
#include "log/ssLogger.h"

namespace StarSeeker
{


ssDBThreadBase::ssDBThreadBase()
{
}

ssDBThreadBase::~ssDBThreadBase()
{
}

bool ssDBThreadBase::Init(const char *pIP, u32 port, const char *pAccount, const char *pPW, const char *pDBName)
{
	return m_mysqlQuery.Init(pIP, port, pAccount, pPW, pDBName);
}

void ssDBThreadBase::HandleMessage(ssMsg_s &m)
{
	//解析网络消息
	ssNetMsgHead* head = (ssNetMsgHead*)m.param[1];
	char* data = (char*)m.param[1];
	bool ret = OnDBMsg(head, data + sizeof(ssNetMsgHead), head->m_dwLen - sizeof(ssNetMsgHead), (u32)m.param[0]);

	if (ret)
	{
		//!!需要对象池
		delete[] data;
	} 
	else
	{
		PostMsg(m);
	}
}

bool ssDBThreadBase::OnDBMsgNullRecord(u32 id, ssNetMsgHead* pHead, const char* pData, const u32 dataLen, u32 connectID)
{
	SS_EXP_TRY
		m_mysqlQuery.QueryByID(id, dataLen, pData);
		if (m_mysqlQuery.GetResultFlag(id) & DB_RESULT_INSERT_ID)
		{
			u32 row = (u32)m_mysqlQuery.GetAffectedRows();
			u32 inId = (u32)m_mysqlQuery.GetInsertID();
			ssDBResParam rp = {};
			//!!需要对象池
			ulint* param = (ulint*)(pData + (dataLen - cg_ulint_size));
			rp.param = *param;
			rp.row = row;
			rp.insertId = inId;
			u32 sendLen = sizeof(ssNetMsgHead) + sizeof(ssDBResParam);
			pHead->m_dwLen = sendLen;
			char* sendBuf = new char[sendLen + 8];
			memcpy(sendBuf, pHead, sizeof(ssNetMsgHead));
			memcpy(sendBuf + sizeof(ssNetMsgHead), &rp, sizeof(ssDBResParam));
			SendResponse(connectID, (ssNetMsgHead*)sendBuf, sendBuf, sendLen);
		}
	SS_EXP_CATCH
		SS_LOG->PrintEx(err.GetErrorMsg());
	SS_EXP_END
	return true;
}

bool ssDBThreadBase::OnDBMsgOneRecord(u32 id, ssNetMsgHead* pHead, const char* pData, const u32 dataLen, u32 connectID)
{
	SS_EXP_TRY
		m_mysqlQuery.QueryByID(id, dataLen, pData);
		ssWriteBytes& wb = m_mysqlQuery.GetOneResult(id);
		u32 row = (u32)m_mysqlQuery.GetRows();
		ssDBResParam rp = {};

		ulint* param = (ulint*)(pData + (dataLen - cg_ulint_size));
		rp.param = *param;
		rp.row = row;
		u32 sendLen = sizeof(ssNetMsgHead) + sizeof(ssDBResParam) + (u32)wb.Size();
		pHead->m_dwLen = sendLen;
		char* sendBuf = new char[sendLen + 8];

		memcpy(sendBuf, pHead, sizeof(ssNetMsgHead));
		memcpy(sendBuf + sizeof(ssNetMsgHead), &rp, sizeof(ssDBResParam));
		if (row>0)
		{
			memcpy(sendBuf + sizeof(ssNetMsgHead) + sizeof(ssDBResParam), wb.Buf(), wb.Size());
		}
		SendResponse(connectID, (ssNetMsgHead*)sendBuf, sendBuf, sendLen);
	SS_EXP_CATCH
		SS_LOG->PrintEx(err.GetErrorMsg());
	SS_EXP_END
	return true;
}

bool ssDBThreadBase::OnDBMsgMultiRecord(u32 id, ssNetMsgHead* pHead, const char* pData, const u32 dataLen, u32 connectID)
{
	SS_EXP_TRY
		m_mysqlQuery.QueryByID(id, dataLen, pData);
		ssMultiLineBuffer& ob = m_mysqlQuery.GetResultSet(id);
		u32 row = (u32)m_mysqlQuery.GetRows();
		ssDBResParam rp = {};

		ulint* param = (ulint*)(pData + (dataLen - cg_ulint_size));
		rp.param = *param;
		rp.row = row;
		u32 sendLen = sizeof(ssNetMsgHead) + sizeof(ssDBResParam) + (u32)ob.Size();
		pHead->m_dwLen = sendLen;
		char* sendBuf = new char[sendLen + 8];
		char* sendFirst = sendBuf;

		memcpy(sendBuf, pHead, sizeof(ssNetMsgHead));
		sendBuf += sizeof(ssNetMsgHead);
		memcpy(sendBuf, &rp, sizeof(ssDBResParam));
		if (row > 0)
		{
			sendBuf += sizeof(ssDBResParam);
			memcpy(sendBuf, ob.Buf(), ob.Size());
		}
		SendResponse(connectID, (ssNetMsgHead*)sendFirst, sendFirst, sendLen);
	SS_EXP_CATCH
		SS_LOG->PrintEx(err.GetErrorMsg());
	SS_EXP_END
	return true;
}

void ssDBThreadBase::OnDBMsgCleanBuffer()
{
	m_mysqlQuery.CleanBuffer();
}

}
